import Module from "module";

export class Node{
    public name: string = '';
    public path: string = '';
    public children: Node[] = [];
    public meta: Record<string,any> = {};
    public component?: any;
    constructor({name,path,children,meta,component}: {name:string,path:string,children:Node[],meta?:Record<string,any>, component?: any}){
        this.name = name;
        this.path = path;
        this.children = children;
        this.meta=meta??{};
        this.component = component;
    }
}

class DocRouteTree{
    public root:Node;
    constructor(){
        this.root = new Node({
            name: 'doc',
            path: '/doc',
            children: [],
        })
    }
    insert(parent: string, node: Node, meta?:Record<string,any>, isSign?: boolean){
        let cur = this.root;
        let stack = [...cur.children];
        let insertSuccess = false;
        while (stack.length){
            let popItem = stack.pop();
            if (popItem){
                if (popItem.name === parent){
                    popItem.children.push(Object.assign({},node));
                    insertSuccess = true;
                    break;
                } else {
                    stack.unshift(...popItem.children);
                }
            }
        }
        if (!insertSuccess){
            if (isSign){
                cur.children.push(Object.assign({}, node));
                return;
            }
            let parentNode = new Node({
                name: parent,
                path: parent.replace('docs-', ''),
                children: [Object.assign({}, node)]
            });
            cur.children.push(Object.assign({}, parentNode));
        }
    }
    toObject(){
        this.normalize()
        return Object.assign({}, this.root);
    }
    normalize(){
        let stack = [...this.findAllParents()];
        let stackLength = stack.length;
        let i=0;
        let j=0;
        while (i < stackLength){
            let children = stack[i].children;
            let childrenLength = children.length;
            if (children && /about/.test(stack[i].path)){
                stack[i].meta.type = 'about';
            }
            while (j<childrenLength){
                let shiftItem = children[j];
                if (shiftItem && /index/.test(shiftItem.path)){
                    stack[i].meta.title = shiftItem.meta.title;
                    children.splice(j,1);
                }
                j++
            }
            i++;
            j=0;
        }
    }
    // 查找所有有子集的节点
    findAllParents(){
        let parents = [];
        let stack = [...this.root.children];
        while (stack.length){
            let shiftItem = stack.shift();
            if (shiftItem && shiftItem.children.length){
                parents.push(shiftItem);
                stack.push(...shiftItem.children);
            }
        }
        return parents;
    }
}
const routeTree = new DocRouteTree();
export function useDocRouterTree(){
    return routeTree.root;
}

export async function generateDocRouter(meta: Record<string,any>){
    const allMarkdown = import.meta.glob('../docs/**/*.md', {eager: true}) as Record<string, Module>;
    const markdownDynamicImport = import.meta.glob('../docs/**/*.md');
    const pathList = Object.keys(allMarkdown).map((path) => {
        return path.replace(/\d\-/,'').replace('..', '').replace('.md', '').replace('/docs/','');
    });
    const staticMarkdownFile = Object.values(allMarkdown);
    const DynamicMarkdownFile = Object.values(markdownDynamicImport);
    const splitArray = pathList.map((path) => path.split('/'));
    for (let i=0;i<splitArray.length;i++){
        const {title, bg, author} = (staticMarkdownFile[i] as Record<string,any>).frontmatter;
        let node = new Node({
            name: `docs-${splitArray[i][0]??''}-${splitArray[i]?.[1] ?? splitArray[i][0]}`,
            path: `${splitArray[i][1] ?? splitArray[i][0]}`,
            children: [],
            component: DynamicMarkdownFile[i],
            meta:{
                ...meta,
                title,
                bg,
                author,
                type: /about/.test(`docs-${splitArray[i][0]??''}-${splitArray[i]?.[1] ?? splitArray[i][0]}`) ? 'about' : 'doc'
            }
        })
        if (splitArray[i].length >= 2){
            routeTree.insert(`docs-${splitArray[i][0]}`,node);
        } else {
            routeTree.insert(`docs-${splitArray[i][0]}`, node, {}, true);
        }
    }
    return routeTree.toObject()
}